package com.saturday.auth.filter;

import com.saturday.common.constants.CommonConsts;
import com.saturday.common.support.UserContextHolder;
import com.saturday.common.util.JwtTokenUtils;
import io.jsonwebtoken.ExpiredJwtException;
import lombok.extern.slf4j.Slf4j;
import org.apache.commons.lang3.StringUtils;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.core.annotation.Order;
import org.springframework.core.env.Environment;
import org.springframework.stereotype.Component;

import javax.servlet.*;
import javax.servlet.http.HttpServletRequest;
import javax.servlet.http.HttpServletResponse;
import java.io.IOException;

@Slf4j
@Component
@Order(10)
public class UserContextFilter implements Filter {
    @Autowired
    private Environment env;

    private String secret;

    /**
     * TODO 定义jwt加密串
     */
    private static final String JWT_SECRET = "";

    @Override
    public void init(FilterConfig filterConfig) throws ServletException {
        log.info("userContextFilter>>>>>>>>>>>>>>init");
        this.secret = env.getProperty("jwt.secret");
        if (StringUtils.isBlank(secret)) {
            secret = JWT_SECRET;
        }
    }

    @Override
    public void doFilter(ServletRequest servletRequest, ServletResponse servletResponse, FilterChain filterChain) throws IOException, ServletException {
        log.info("userContextFilter>>>>>>>>>>>>>>doFilter");
        HttpServletRequest request = (HttpServletRequest) servletRequest;
        HttpServletResponse response = (HttpServletResponse) servletResponse;
        String sessionId = request.getHeader(CommonConsts.CURRENT_USER_HEADER);
        if (StringUtils.isBlank(sessionId)) {
            sessionId = (String) request.getAttribute(CommonConsts.CURRENT_USER_HEADER);
        }

        if (StringUtils.isBlank(sessionId)) {

            String token = getToken(request);

            try {
                if (StringUtils.isBlank(sessionId) && StringUtils.isNotBlank(token)) {
                    sessionId = JwtTokenUtils.getSessionIdFromToken(token, this.secret);
                }
            } catch (ExpiredJwtException e) {
                log.error("JWT 解析token过期异常:{}", e);
            } catch (Exception e) {
                log.error("JWT 解析token异常:{}", e);
            }
        }

        if (StringUtils.isBlank(sessionId)) {
            filterChain.doFilter(request, response);
            return;
        }
        try {
            UserContextHolder.setSessionId(sessionId);
            filterChain.doFilter(request, response);
        } catch (Exception e) {
            log.error("系统异常：{}", e.getMessage());
            throw new RuntimeException("系统异常");
        } finally {
            try {
                log.info("清空透传用户信息");
                UserContextHolder.clear();
            } catch (Exception e) {
                log.error("透传用户信息清空异常：{}", e);
            }
        }
    }

    private String getToken(HttpServletRequest request) {
        String token = request.getHeader(CommonConsts.TOKEN_NAME);

        if (StringUtils.isEmpty(token)) {
            token = request.getHeader(CommonConsts.AUTHENTICATION);
            if (StringUtils.isNotBlank(token) && token.startsWith(CommonConsts.PREFIX)) {
                token = token.substring(CommonConsts.PREFIX.length());
            }
        }

        if (StringUtils.isEmpty(token)) {
            token = request.getParameter(CommonConsts.TOKEN_NAME);
        }

        return token;
    }

    @Override
    public void destroy() {
        Filter.super.destroy();
    }
}
